﻿using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;

namespace ASPMVC
{
    public class Generate
    {
        Project project = new Project();
        public String outputDir = "";

        public void readXML(String path)
        {
            XmlSerializer deserializer = new XmlSerializer(typeof(Project));
            TextReader textReader = new StreamReader(path);
            project = (Project)deserializer.Deserialize(textReader);
            textReader.Close();
            //Console.WriteLine(project.application.author);
        }

        public void process()
        {
            System.IO.Directory.CreateDirectory(outputDir);
            System.IO.Directory.CreateDirectory(outputDir+ "/View");
            process_controller();
            process_model();
            process_scaffold();
        }

        public void process_controller()
        {
            List<Controller> controllers = project.controllers;
            int size_controller = controllers.Count;
            for (int i = 0; i < size_controller; i++)
            {
                Controller controller = controllers[i];
                System.IO.Directory.CreateDirectory(outputDir + "/View/" + controller.name);

                String str_attr = "";
                int size_atrr = controller.attributes.Count;
                for (int ii = 0; ii < size_atrr; ii++)
                {
                    ASPMVC.Attribute attr = controller.attributes[ii];
                    str_attr = str_attr + attr.type + " " + attr.name + "\r\n";
                }

                String str_function = "";
                int size_function = controller.functions.Count;
                for (int ii = 0; ii < size_atrr; ii++)
                {
                    ASPMVC.Function function = controller.functions[ii];
                    str_function = str_function + "public void " + function.name + "()\r\n{\r\n}";
                }

                String str_view = "";
                int size_view = controller.views.Count;
                for (int ii = 0; ii < size_view; ii++)
                {
                    View view = controller.views[ii];
                    str_view = str_view + "public void " + view.name + "()\r\n{\r\n}";

                    TextWriter txt_view = new StreamWriter(outputDir + "/View/" + controller.name + "/" + view.name + ".aspx");
                    String file_view = GetResourceTextFile("view");
                    txt_view.WriteLine(file_view);
                    txt_view.Close();
                }

                String file = GetResourceTextFile("controller");
                file.Replace("//nameApp//", project.application.name);
                file.Replace("//nameClass//", controller.name);
                file.Replace("//attributes//", str_attr);
                file.Replace("//views//", str_view);
                file.Replace("//functions//", str_function);

                TextWriter tw = new StreamWriter(outputDir + "/" + controller.name + "Controller.cs");
                tw.WriteLine(file);
                tw.Close();

                TextWriter index = new StreamWriter(outputDir + "/View/" + controller.name + "/index.aspx");
                file = GetResourceTextFile("index");
                index.WriteLine(file);
                index.Close();
            }
        }

        public void process_model()
        {
            List<Model> models = project.models;
            int size_model = models.Count;
            for (int i = 0; i < size_model; i++)
            {
                Model model = models[i];               

                String str_attr = "";
                int size_atrr = model.attributes.Count;
                for (int ii = 0; ii < size_atrr; ii++)
                {
                    ASPMVC.Attribute attr = model.attributes[ii];
                    str_attr = str_attr + "public " + attr.type + " " + attr.name + " { get; set; } \r\n";
                }

                String str_function = "";
                int size_function = model.functions.Count;
                for (int ii = 0; ii < size_function; ii++)
                {
                    ASPMVC.Function function = model.functions[ii];
                    str_function = str_function + "public void " + function.name + "()\r\n{\r\n}";
                }

                String file = GetResourceTextFile("controller");
                file.Replace("//nameApp//", project.application.name);
                file.Replace("//nameClass//", model.name);
                file.Replace("//attributes//", str_attr);
                
                file.Replace("//functions//", str_function);

                TextWriter tw = new StreamWriter(outputDir + "/" + model.name + "Model.cs");
                tw.WriteLine(file);
                tw.Close();

                
            }
        }

        public void process_scaffold()
        {
            List<Scaffold> scaffolds = project.scaffolds;
            int size_scaffold = scaffolds.Count;
            for (int i = 0; i < size_scaffold; i++)
            {
                Scaffold scaffold = scaffolds[i];
                System.IO.Directory.CreateDirectory(outputDir + "/View/" + scaffold.name);

                String str_attr = "";
                String str_attr_create = "";
                String str_attr_delete = "";
                String str_attr_list_th = "";
                String str_attr_list_td = "";
                int size_atrr = scaffold.attributes.Count;
                for (int ii = 0; ii < size_atrr; ii++)
                {
                    ASPMVC.Attribute attr = scaffold.attributes[ii];
                    str_attr = str_attr + attr.type + " " + attr.name + "\r\n";

                    str_attr_create = str_attr_create +
                    "<div class=\"editor-label\">\r\n" +
                        "\t<%: Html.LabelFor(model => model." + attr.name + ") %>\r\n" +
                    "</div>\r\n" +
                    "<div class=\"editor-field\">\r\n" +
                        "\t<%: Html.EditorFor(model => model." + attr.name + ") %>\r\n" +
                        "\t<%: Html.ValidationMessageFor(model => model." + attr.name + ") %>\r\n" +
                    "</div>\r\n";

                    str_attr_delete = str_attr_delete +
                    "<div class=\"display-label\">" + attr.name + "</div>\r\n" +
                    "<div class=\"display-field\">\r\n" +
                        "\t<%: Html.DisplayFor(model => model." + attr.name + ") %>\r\n" +
                    "</div>\r\n"; 
   
                    str_attr_list_th = str_attr_list_th +
                    "<th>\r\n" +
                        "\t" + attr.name + "\r\n" +
                    "</th>\r\n";

                    str_attr_list_td = str_attr_list_td +
                    "<td>\r\n" +
                        "\t<%: Html.DisplayFor(modelItem => item." + attr.name + ") %>" + "\r\n" +
                    "</td>\r\n";
                    
                }

                String str_function = "";
                int size_function = scaffold.functions.Count;
                for (int ii = 0; ii < size_function; ii++)
                {
                    ASPMVC.Function function = scaffold.functions[ii];
                    str_function = str_function + "public void " + function.name + "()\r\n{\r\n}";
                }

                String str_view = "";
                int size_view = scaffold.views.Count;
                for (int ii = 0; ii < size_view; ii++)
                {
                    View view = scaffold.views[ii];
                    str_view = str_view + "public void " + view.name + "()\r\n{\r\n}";

                    TextWriter txt_view = new StreamWriter(outputDir + "/View/" + scaffold.name + "/" + view.name + ".aspx");
                    String file_view = GetResourceTextFile("view");
                    txt_view.WriteLine(file_view);
                    txt_view.Close();
                }

                String file = GetResourceTextFile("controller");
                file.Replace("//nameApp//", project.application.name);
                file.Replace("//nameClass//", scaffold.name);
                file.Replace("//attributes//", str_attr);
                file.Replace("//views//", str_view);
                file.Replace("//functions//", str_function);

                TextWriter tw = new StreamWriter(outputDir + "/" + scaffold.name + "Controller.cs");
                tw.WriteLine(file);
                tw.Close();
            
                TextWriter create = new StreamWriter(outputDir + "/View/" + scaffold.name + "/Create.aspx");
                file = GetResourceTextFile("create");
                file.Replace("//nameApp//", project.application.name);
                file.Replace("//nameClass//", scaffold.name);
                file.Replace("//attr_create//", str_attr_create);
                create.WriteLine(file);
                create.Close();

                TextWriter delete = new StreamWriter(outputDir + "/View/" + scaffold.name + "/Delete.aspx");
                file = GetResourceTextFile("delete");
                file.Replace("//nameApp//", project.application.name);
                file.Replace("//nameClass//", scaffold.name);
                file.Replace("//attr_delete//", str_attr_delete);
                delete.WriteLine(file);
                delete.Close();

                TextWriter detail = new StreamWriter(outputDir + "/View/" + scaffold.name + "/Detail.aspx");
                file = GetResourceTextFile("details");
                file.Replace("//nameApp//", project.application.name);
                file.Replace("//nameClass//", scaffold.name);
                file.Replace("//attr_delete//", str_attr_delete);
                detail.WriteLine(file);
                detail.Close();

                TextWriter edit = new StreamWriter(outputDir + "/View/" + scaffold.name + "/Edit.aspx");
                file = GetResourceTextFile("edit");
                file.Replace("//nameApp//", project.application.name);
                file.Replace("//nameClass//", scaffold.name);
                file.Replace("//attr_create//", str_attr_create);
                edit.WriteLine(file);
                edit.Close();

                TextWriter index = new StreamWriter(outputDir + "/View/" + scaffold.name + "/Index.aspx");
                file = GetResourceTextFile("list");
                file.Replace("//nameApp//", project.application.name);
                file.Replace("//nameClass//", scaffold.name);
                file.Replace("//str_attr_list_th//", str_attr_list_th);
                file.Replace("//str_attr_list_td//", str_attr_list_td);
                index.WriteLine(file);
                index.Close();
                

                str_attr = "";
                size_atrr = scaffold.attributes.Count;
                for (int ii = 0; ii < size_atrr; ii++)
                {
                    ASPMVC.Attribute attr = scaffold.attributes[ii];
                    str_attr = str_attr + "public " + attr.type + " " + attr.name + " { get; set; } \r\n";
                }

                str_function = "";
                size_function = scaffold.functions.Count;
                for (int ii = 0; ii < size_function; ii++)
                {
                    ASPMVC.Function function = scaffold.functions[ii];
                    str_function = str_function + "public void " + function.name + "()\r\n{\r\n}";
                }

                file = GetResourceTextFile("controller");
                file.Replace("//nameApp//", project.application.name);
                file.Replace("//nameClass//", scaffold.name);
                file.Replace("//attributes//", str_attr);

                file.Replace("//functions//", str_function);

                tw = new StreamWriter(outputDir + "/" + scaffold.name + "Model.cs");
                tw.WriteLine(file);
                tw.Close();


            }
        }

        public string GetResourceTextFile(String name)
        {
            string result = string.Empty;
            using (Stream stream = GetType().Module.Assembly.GetManifestResourceStream("ASPMVC.Tpl."+name+".tpl"))
            {                
                using (StreamReader sr = new StreamReader(stream))
                {
                    result = sr.ReadToEnd();
                    //Console.WriteLine(result);
                }
            }
            return result;
        }

        
    }
}
